package com.campus.help.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.help.entity.LaborType;
import com.campus.help.exception.BusinessException;
import com.campus.help.mapper.LaborMapper;
import com.campus.help.mapper.LaborTypeMapper;
import com.campus.help.service.LaborTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 劳务类型服务实现类
 *
 * @author campus-help
 * @since 2025-09-18
 */
@Slf4j
@Service
public class LaborTypeServiceImpl extends ServiceImpl<LaborTypeMapper, LaborType> implements LaborTypeService {

    @Autowired
    private LaborMapper laborMapper;

    @Override
    public IPage<LaborType> getLaborTypePage(Integer page, Integer size, String typeName, Integer status) {
        log.info("分页查询劳务类型，页码：{}，大小：{}，类型名称：{}，状态：{}", page, size, typeName, status);
        
        Page<LaborType> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<LaborType> queryWrapper = new LambdaQueryWrapper<>();
        
        // 类型名称模糊查询
        if (StringUtils.hasText(typeName)) {
            queryWrapper.like(LaborType::getTypeName, typeName);
        }
        
        // 状态筛选
        if (status != null) {
            queryWrapper.eq(LaborType::getStatus, status);
        }
        
        // 按排序值和创建时间排序
        queryWrapper.orderByAsc(LaborType::getSortOrder)
                   .orderByAsc(LaborType::getCreateTime);
        
        return this.page(pageParam, queryWrapper);
    }

    @Override
    public List<LaborType> getEnabledTypes() {
        log.info("获取启用状态的劳务类型列表");
        return baseMapper.selectEnabledTypes();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LaborType createLaborType(LaborType laborType) {
        log.info("创建劳务类型：{}", laborType.getTypeName());
        
        // 检查类型名称是否重复
        if (checkTypeNameExists(laborType.getTypeName(), null)) {
            throw new BusinessException("类型名称已存在");
        }
        
        // 设置排序值
        if (laborType.getSortOrder() == null) {
            laborType.setSortOrder(baseMapper.getNextSortOrder());
        }
        
        // 设置默认值
        if (laborType.getStatus() == null) {
            laborType.setStatus(1);
        }
        if (laborType.getIsDefault() == null) {
            laborType.setIsDefault(0);
        }
        if (laborType.getColor() == null) {
            laborType.setColor("#4f46e5");
        }
        
        laborType.setCreateTime(LocalDateTime.now());
        laborType.setUpdateTime(LocalDateTime.now());
        
        this.save(laborType);
        
        log.info("劳务类型创建成功，ID：{}", laborType.getId());
        return laborType;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LaborType updateLaborType(LaborType laborType) {
        log.info("更新劳务类型，ID：{}", laborType.getId());
        
        // 检查类型是否存在
        LaborType existingType = this.getById(laborType.getId());
        if (existingType == null) {
            throw new BusinessException("劳务类型不存在");
        }
        
        // 检查是否为系统默认类型（默认类型不允许修改某些字段）
        if (existingType.getIsDefault() == 1) {
            log.warn("尝试修改系统默认类型：{}", existingType.getTypeName());
            // 系统默认类型只允许修改描述、图标、颜色、状态
            existingType.setDescription(laborType.getDescription());
            existingType.setIcon(laborType.getIcon());
            existingType.setColor(laborType.getColor());
            existingType.setStatus(laborType.getStatus());
            existingType.setRemark(laborType.getRemark());
            laborType = existingType;
        } else {
            // 检查类型名称是否重复
            if (checkTypeNameExists(laborType.getTypeName(), laborType.getId())) {
                throw new BusinessException("类型名称已存在");
            }
        }
        
        laborType.setUpdateTime(LocalDateTime.now());
        this.updateById(laborType);
        
        log.info("劳务类型更新成功");
        return laborType;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteLaborType(Long typeId) {
        log.info("删除劳务类型，ID：{}", typeId);
        
        // 检查类型是否存在
        LaborType laborType = this.getById(typeId);
        if (laborType == null) {
            throw new BusinessException("劳务类型不存在");
        }
        
        // 检查是否为系统默认类型
        if (laborType.getIsDefault() == 1) {
            throw new BusinessException("系统默认类型不允许删除");
        }
        
        // 检查是否有劳务使用该类型
        Long usageCount = getTypeUsageCount(typeId);
        if (usageCount > 0) {
            throw new BusinessException("该类型下还有 " + usageCount + " 个劳务，不能删除");
        }
        
        boolean result = this.removeById(typeId);
        log.info("劳务类型删除成功");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteLaborTypes(List<Long> typeIds) {
        log.info("批量删除劳务类型，数量：{}", typeIds.size());
        
        for (Long typeId : typeIds) {
            deleteLaborType(typeId);
        }
        
        log.info("批量删除劳务类型成功");
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long typeId, Integer status) {
        log.info("更新劳务类型状态，ID：{}，状态：{}", typeId, status);
        
        LaborType laborType = this.getById(typeId);
        if (laborType == null) {
            throw new BusinessException("劳务类型不存在");
        }
        
        laborType.setStatus(status);
        laborType.setUpdateTime(LocalDateTime.now());
        
        boolean result = this.updateById(laborType);
        log.info("劳务类型状态更新成功");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSortOrder(Long typeId, Integer sortOrder) {
        log.info("更新劳务类型排序，ID：{}，排序值：{}", typeId, sortOrder);
        
        int result = baseMapper.updateSortOrder(typeId, sortOrder);
        if (result > 0) {
            log.info("劳务类型排序更新成功");
            return true;
        }
        
        throw new BusinessException("劳务类型排序更新失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateSortOrder(List<Long> typeIds) {
        log.info("批量更新劳务类型排序，数量：{}", typeIds.size());
        
        for (int i = 0; i < typeIds.size(); i++) {
            updateSortOrder(typeIds.get(i), i + 1);
        }
        
        log.info("批量更新劳务类型排序成功");
        return true;
    }

    @Override
    public List<LaborType> getDefaultTypes() {
        log.info("获取系统默认类型列表");
        return baseMapper.selectDefaultTypes();
    }

    @Override
    public boolean checkTypeNameExists(String typeName, Long excludeId) {
        LaborType existingType = baseMapper.selectByTypeName(typeName, excludeId);
        return existingType != null;
    }

    @Override
    public Long getTypeUsageCount(Long typeId) {
        LambdaQueryWrapper<com.campus.help.entity.Labor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(com.campus.help.entity.Labor::getTypeId, typeId);
        return laborMapper.selectCount(queryWrapper);
    }
}
